/**
 * 原型：prototype
 *
 * 我们所创建的每一个函数，解析器都会向函数中添加一个属性prototype，这个属性对应着一个对象，这个对象就是我们所谓的原型对象。
 *
 * 如果我们的函数作为普通函数调用prototype没有任何作用
 * 当函数以构造函数的形式调用时，它所创建的对象中都会有一个隐含的属性，指向该函数的原型对象,我们可以通过__proto__来访问该属性
 *
 * 原型对象就相当于一个公共的区域，所有同一个类的实例都可以访问到这个原型对象，所以
 * 我们可以将对象中共有的属性，统一设置到原型对象中。
 *
 * 当我们访问对象的一个属性或者方法时，它会先在对象自身寻找，如果有则直接使用，如果没有则会去原型对象中寻找，如果找到则直接使用。
 *
 * 以后我们创建构造函数时，可以将这些对象共有的属性和方法，统一添加到构造函数的原型对象中，这样不用分别为每一个对象添加，
 * 就可以使每个对象都具有这些属性和方法了。
 *
 * 使用in检查对象中是否含有某个属性时，如果对象中没有但是原型中有，也会返回true
 * 可以使用hasOwnProperty()检查对象自身中（不包括原型）是否含有该属性，使用该方法只有当对象自身中含有该属性时才会返回true
 *
 * 原型的对象也是对象，所有它也有原型，当我们使用一个对象的属性或者方法时，会先在自身寻找
 * 自身中如果有，则直接使用，如果没有这去原型对象中寻找
 * 如果原型对象中有，则使用，如果没有则去原型的原型中寻找，直到找到Object对象的原型，
 * Object对象的原型没有原型，如果在Object中依然没有找到，则返回undefined
 * */

function Person() {

}
Person.prototype.name = "我是原型中的name属性";
Person.prototype.fun = function () {
    console.log("我是原型中的方法");
};

console.log(Person.prototype);

var person = new Person(); // 以构造函数的方式调用该函数
var person2 = new Person();
// person2.name = "我是对象中的属性";

console.log(person.__proto__);

console.log(Person.prototype === person.__proto__);

console.log(person.name);
console.log(person2.name);

person.fun();

console.log("当前对象的原型： "+person.__proto__);
console.log("当前对象的原型的原型： "+person.__proto__.__proto__); // 找到头了~~~~
console.log("当前对象的原型的原型的原型： "+person.__proto__.__proto__.__proto__);

